package test.my.com.myapplicationtest.wave_view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import test.my.com.myapplicationtest.utils.DensityUtil;

/**
 * Author : Cooper
 * Time : 2017/4/6  17:45
 * Description :
 */

public class WaveView extends View {

    // 波纹颜色
    private static final int WAVE_PAINT_COLOR = 0x880000aa;
    // y = Asin(wx+b)+h
    private static final float STRETCH_FACTOR_A = 20;
    private static final int OFFSET_Y = 0;
    // 第一条水波移动速度
    private static final int TRANSLATE_X_SPEED_ONE = 2;
    // 第二条水波移动速度
    private static final int TRANSLATE_X_SPEED_TWO = 2;
    private float mCycleFactorW;

    private int mTotalWidth, mTotalHeight;
    private float[] mYPositionsSinOne;
    private float[] mYPositionsSinTwo;
    private float[] mYPositionsCos;
    private float[] mResetOneYPositions;
    private float[] mResetTwoYPositions;
    private float[] mResetThreeYPositions;
    private int mXOffsetSpeedOne;
    private int mXOffsetSpeedTwo;
    private int mXOneOffset;
    private int mXTwoOffset;

    private Paint mWaveOnePaint;
    private Paint mWaveTwoPaint;
    private Paint mWaveThreePaint;
    private DrawFilter mDrawFilter;

    private int index ;

    public WaveView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 将dp转化为px，用于控制不同分辨率上移动速度基本一致
        mXOffsetSpeedOne = DensityUtil.dip2px(context, TRANSLATE_X_SPEED_ONE);
        mXOffsetSpeedTwo = DensityUtil.dip2px(context, TRANSLATE_X_SPEED_TWO);

        // 初始绘制波纹的画笔
        mWaveOnePaint = new Paint();
        mWaveOnePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        // 去除画笔锯齿
        mWaveOnePaint.setAntiAlias(true);
        // 设置风格为实线
        mWaveOnePaint.setStyle(Paint.Style.FILL);
        // 设置画笔颜色
        mWaveOnePaint.setColor(WAVE_PAINT_COLOR);

        // 初始绘制波纹的画笔
        mWaveTwoPaint = new Paint();
        mWaveTwoPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        // 去除画笔锯齿
        mWaveTwoPaint.setAntiAlias(true);
        // 设置风格为实线
        mWaveTwoPaint.setStyle(Paint.Style.FILL);
        // 设置画笔颜色
        mWaveTwoPaint.setColor(Color.GREEN);

        // 初始绘制波纹的画笔
        mWaveThreePaint = new Paint();
        mWaveThreePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        // 去除画笔锯齿
        mWaveThreePaint.setAntiAlias(true);
        // 设置风格为实线
        mWaveThreePaint.setStyle(Paint.Style.FILL);
        // 设置画笔颜色
        mWaveThreePaint.setColor(Color.YELLOW);

        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 从canvas层面去除绘制时锯齿
//        canvas.setDrawFilter(mDrawFilter);
        for (int i = 0; i < mTotalWidth; i++) {

            // 减400只是为了控制波纹绘制的y的在屏幕的位置，大家可以改成一个变量，然后动态改变这个变量，从而形成波纹上升下降效果
            // 绘制第一条水波纹
            canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i]-100, i,
                    mTotalHeight,
                    mWaveOnePaint);

            // 绘制第二条水波纹
            canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i]-100, i,
                    mTotalHeight,
                    mWaveTwoPaint);
//
////            // 绘制第三条水波纹
            canvas.drawLine(i, mTotalHeight - mResetThreeYPositions[i]-100, i,
                    mTotalHeight,
                    mWaveThreePaint);
        }

//        // 改变两条波纹的移动点
//        mXOneOffset += mXOffsetSpeedOne;
//        mXTwoOffset += mXOffsetSpeedTwo;
//
//        // 如果已经移动到结尾处，则重头记录
//        if (mXOneOffset >= mTotalWidth) {
//            mXOneOffset = 0;
//        }
//        if (mXTwoOffset > mTotalWidth) {
//            mXTwoOffset = 0;
//        }
//
//        // 引发view重绘，一般可以考虑延迟20-30ms重绘，空出时间片
//        postInvalidate();


        canvas.drawLine(index, mTotalHeight - mResetOneYPositions[index]-100, index,
                mTotalHeight,
                mWaveOnePaint);

        // 绘制第二条水波纹
        canvas.drawLine(index, mTotalHeight - mResetTwoYPositions[index]-100, index,
                mTotalHeight,
                mWaveTwoPaint);
//
////            // 绘制第三条水波纹
        canvas.drawLine(index, mTotalHeight - mResetThreeYPositions[index]-100, index,
                mTotalHeight,
                mWaveThreePaint);
    }

    private void resetPositonY() {
        // mXOneOffset代表当前第一条水波纹要移动的距离
        int yOneInterval = mYPositionsSinOne.length - mXTwoOffset;
        // 使用System.arraycopy方式重新填充第一条波纹的数据
        System.arraycopy(mYPositionsSinOne, mXTwoOffset, mResetOneYPositions, 0, yOneInterval);
        System.arraycopy(mYPositionsSinOne, 0, mResetOneYPositions, yOneInterval, mXTwoOffset);

        int yTwoInterval = mYPositionsSinTwo.length - mXTwoOffset;
        System.arraycopy(mYPositionsSinTwo, mXTwoOffset, mResetTwoYPositions, 0,
                yTwoInterval);
        System.arraycopy(mYPositionsSinTwo, 0, mResetTwoYPositions, yTwoInterval, mXTwoOffset);

        int ythreeInterval = mYPositionsCos.length - mXTwoOffset;
        System.arraycopy(mYPositionsCos, mXTwoOffset, mResetThreeYPositions, 0,
                ythreeInterval);
        System.arraycopy(mYPositionsCos, 0, mResetThreeYPositions, ythreeInterval, mXTwoOffset);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 记录下view的宽高
        mTotalWidth = w;
        mTotalHeight = h;
        // 用于保存原始波纹的y值 sin
        mYPositionsSinOne = new float[mTotalWidth];
        // 用于保存原始波纹的y值 sin
        mYPositionsSinTwo = new float[mTotalWidth];
        // 用于保存原始波纹的y值 cos
        mYPositionsCos = new float[mTotalWidth];
        // 用于保存波纹一的y值
        mResetOneYPositions = new float[mTotalWidth];
        // 用于保存波纹二的y值
        mResetTwoYPositions = new float[mTotalWidth];
        // 用于保存波纹三的y值
        mResetThreeYPositions = new float[mTotalWidth];

        // 将周期定为view总宽度
        mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);

        // 根据view总宽度得出所有对应的y值
        for (int i = 0; i < mTotalWidth; i++) {
            mYPositionsSinOne[i] = (float) (40 * Math.sin(mCycleFactorW * i)/* + OFFSET_Y*/);
//            mYPositionsSinOne[i] = (float) (Math.sin(mCycleFactorW * i)/* + OFFSET_Y*/);
        }

//        // 根据view总宽度得出所有对应的y值
        for (int i = 0; i < mTotalWidth; i++) {
            mYPositionsSinTwo[i] = (float) (40 * Math.sin(mCycleFactorW * i - Math.PI) /*+ OFFSET_Y*/);
        }
//
//        // 根据view总宽度得出所有对应的y值
        for (int i = 0; i < mTotalWidth; i++) {
            mYPositionsCos[i] = (float) (40 * Math.cos(mCycleFactorW * i) /*+ OFFSET_Y*/);
        }

        ValueAnimator valueAnimator = ValueAnimator.ofInt(0,mTotalWidth);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mXTwoOffset = (int) animation.getAnimatedValue();
                resetPositonY();
                invalidate();
            }
        });
        valueAnimator.setDuration(50000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setRepeatCount(10000);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.start();
    }
}